package commons.jdbc.reflect;




import commons.jdbc.annotation.*;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 反射获得实体和字段  解析annotation  获取注解中值 没有value 属性名字  类名
 * @author 930437
 *
 */
public class ReflectEntityField {

    /**
     * 利用注解获得表名
     *
     * @param cl
     * @return
     */
    static public String getTableName(Class<?> cl) {
        String tableName = null;
        // 判断这个class类是否被Table 注解了
        if (cl.isAnnotationPresent(Table.class)) {
            // 判断是value 是否有值
            Table table = (Table) cl.getAnnotation(Table.class);
            // 获得value 如果value=""
            tableName = table.value();
            // 如果value没有值
            if (tableName.length() == 0) {
                // 获得类名等于表名
                tableName = cl.getSimpleName();// Admin
            }
        }
        //返回数据库表名
        return tableName;//A   Company
    }

    /**
     * 获得主键名
     *
     * @param cl
     * @return
     */

    static public String getPrimaryKeyName(Class<?> cl) {
        //主键名
        String primaryKeyName = null;
        //字段对象
        Field primaryKeyField = getPrimaryKeyField(cl);
        // 获得主键中的 value值
        if (primaryKeyField != null) {
            primaryKeyName = ((Column) primaryKeyField.getAnnotation(Column.class)).value();
            // 如果是"" 说明属性名就是字段名
            if (primaryKeyName.length() == 0) {
                primaryKeyName = primaryKeyField.getName();
            }
        }
        return primaryKeyName;
    }

    /**
     * 返回主键字段
     *
     * @param cl
     * @return
     */
    static public Field getPrimaryKeyField(Class<?> cl) {
        // 获得所有字段
        Field[] fields = cl.getDeclaredFields();
        if (fields != null) {
            // 循环字段
            for (Field field : fields) {
                // 判断是否PrimaryKey注解
                if (field.isAnnotationPresent(PrimaryKey.class) && field.isAnnotationPresent(Column.class)) {
                    return field;
                }
            }
        }
        return null;
    }

    /**
     * 是否自动增长
     *
     * @param cl
     * @return
     */
    static public boolean getIsAutoIncrease(Class<?> cl) {
        // 获得主键字段
        Field primaryKeyField = getPrimaryKeyField(cl);
        if (primaryKeyField != null) {
            return primaryKeyField.getAnnotation(PrimaryKey.class).isAutoIncrease();
        }
        return false;
    }

    /**
     * 获得列的名字
     *
     * @param field
     * @return
     * @return
     */
    static public String getColumnName(Field field) {
        // 判断注解
        if (field.isAnnotationPresent(Column.class)) {
            // 获得字段名
            String fieldName = field.getAnnotation(Column.class).value();
            //
            if (fieldName.length() == 0) {
                fieldName = field.getName();
            }
            return fieldName;
        }
        System.err.println("---属性注解有误-----");

        return null;
    }
    /**
     * 获得所有字段以及该字段的值
     * @param t
     * @return
     */

    static public <T> Map<String, Object> getColumnValue(T t) {
        Map<String, Object> columnValue = null;
        // 获得所有属性
        Field[] fields = t.getClass().getDeclaredFields();
        if (fields != null) {
            columnValue = new HashMap<>();
            for (Field field : fields) {
                // 是否是数据库对应的字段
                if (field.isAnnotationPresent(Column.class)) {
                    String fieldName = field.getAnnotation(Column.class).value();
                    if (fieldName.length() == 0) {
                        fieldName = field.getName();
                    }
                    field.setAccessible(true);// 省略 getName()
                    try {
                        columnValue.put(fieldName, field.get(t));
                    } catch (IllegalArgumentException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

        return columnValue;
    }
}
